Technote 1107

Extensible Folder Manager

Greg Robbins and John Montbriand, 1997
Apple Developer Technical Support (DTS)
devsupport@apple.com

CONTENTS

If the Extensible Folder Manager is Present...

Folder Descriptors

Extensible Folder Manager Routines

Folder Routing Routines and Structures

Mac OS 8 includes a new Extensible Folder Manager for use by system software and by applications. The Extensible Folder Manager supports FindFolder as well as additional functionality:

  • Developers can add folders to the system that can be located via FindFolder
  • Folders can be nested within other folders that are locatable with FindFolder
  • Calls are available to provide routing information for future versions of the Finder.

    This document describes the Extensible Folder Manager that ships with Mac OS 8 and with future system releases.

If the Extensible Folder Manager is Present...


A new bit in the Gestalt selector gestaltFindFolderAttr ('fold') has been defined to indicate the presence of the Extensible Folder Manager. If the Extensible Folder Manager is present gestaltFolderDescSupport=1 bit, will be set to one. For example, the following routine returns true if the Extensible Folder Manager is present:

   #define gestaltFolderDescSupport 1 
    Boolean EFMExists(void) {
       long response;
       if (Gestalt(gestaltFindFolderAttr, &response) != noErr)
           response = 0;
       return ((response & (1 << gestaltFolderDescSupport)) != 0);
   }

Folder Descriptors

The Extensible Folder Manager identifies each folder using the FolderType data type. The type FolderType is equivalent to the OSType passed to FindFolder to identify the target folder. It is defined as:

typedef OSType FolderType;

The Extensible Folder Manager describes each folder that can be found with FindFolder in a folder descriptor. A folder descriptor does not necessarily describe an existing folder. Rather, it describes how the system will find a folder if it exists, and how to create it if it doesn't exist. In particular, the descriptor includes the parent folder type of the target folder and the name of the target folder, along with some auxiliary information. The Folder Descriptor data structure is defined as:

typedef struct FolderDesc {
      Size            descSize;       /* size of this record */
      FolderType      foldType;       /* OSType identifying this folder */
      FolderDescFlags flags;          /* see 'Folder Properties' below */
      FolderClass     foldClass;      /* relative to parent or special */
      FolderType      foldLocation;   /* parent folder or special kind */
      OSType          badgeSignature; /* creator type for locating icon badge */
      OSType          badgeType;      /* file type for locating icon badge */
      UInt32          reserved;       /* reserved for use by system software */
      Str63           name;           /* name of this folder for type kRelativeFolder */
   };

foldType. The field foldType is the OSType for the target folder.

foldClass and foldLocation. The fields foldClass and foldLocation tell FindFolder how to locate the folder or where to create it. foldClass indicates if the folder is relative or special. Special folders are in locations hard wired into the Extensible Folder Manager, and can be found using special rules. Examples of special folders are the root directory of a disk and the System Folder on a disk.

NOTE:
Most folder descriptors are for relative folders. For a relative folder, the foldLocation field specifies the FolderType of the parent folder of the target. For example, in the folder descriptor for the Extensions folder, the folder class is relative and the folder location is kSystemFolderType.

The Extensible Folder Manager identifies each folder class using using the FolderClass data type which is equivalent to the four character OSType:

typedef OSType FolderClass;

Folders are currently classified into two different categories, as follows:

enum {
      kRelativeFolder  = 'relf',  /* folder contained in another folder */
      kSpecialFolder   = 'spcf'   /* special folder found at run time */
   };

The FolderClass specifies how the FolderLocation should be interpreted. If FolderClass is kRelativeFolder, FolderLocation contains the FolderType of the parent folder, and name contains the name of the folder. If FolderClass is kSpecialFolder, the folder is located algorithmically, according to the constant supplied as the FolderLocation (kBlessedFolder or kRootFolder).

There are two special folder locations that may be specified in the foldLocation field. Relative folders specify the folder type for the enclosing folder in the foldLocation field. The two special types are:

/* special folder locations */
   enum {
      kBlessedFolder  = 'blsf',  /* blessed folder */
      kRootFolder     = 'rotf'   /* disk root folder */
   };

name. The field name in a folder descriptor specifies the name of the target folder. For relative folders, this name will be exactly the name of the desired folder. For special folders, the actual target folder may have a different name that the name specified in the folder descriptor. For example, the System Folder is often given a different name, but it can still be located with FindFolder.

flags. The flags field of a folder descriptor specify if a folder is created during startup, if the name of the folder is locked when the folder is created, and if the folder is created invisible.

The FolderDescFlags describe special behavior applying to a folder. Its data type is defined as an unsigned 32 bit integer:

typedef UInt32 FolderDescFlags;

Currently, the flags that are defined are as follows (all other bits are reserved for future use and should be set to zero):

enum {
      kPersistentFolderDesc     = 1L << 0,  /* folder desc persists across boots */
      kCreateFolderAtBoot       = 1L << 1,  /* folder created at boot if needed */
      kFolderCreatedInvisible   = 1L << 2,  /* folder created as invisible */
      kFolderCreatedNameLocked  = 1L << 3   /* folder created with locked name */
   };

The persistent bit is not currently supported in Mac OS 8, and is ignored.

badgeSignature and badgeType. The badgeSignature and badgeType fields of the folder descriptor are currently unused and should be set to 0.


Extensible Folder Manager Routines

Original Routines

The call FindFolder remains unchanged, as documented in Inside Macintosh: Macintosh Toolbox Essentials. FindFolder can now be used to locate folders registered using the new routines described below.

Folder Descriptor Administration Routines

The following routines can be used for registering folders with the Extensible Folder Manager as well as querying the Extensible Folder Manager for information about registered folders. These routines are found in FoldersLib, a fat library residing in the System file.

AddFolderDescriptor

pascal OSErr AddFolderDescriptor(FolderType foldType,
                         FolderDescFlags flags,
                         FolderClass foldClass,
                         FolderLocation foldLocation,
                         OSType badgeSignature,
                         OSType badgeType, 
                         Str63 name,
                         Boolean replaceFlag);

AddFolderDescriptor copies the supplied information into a new descriptor entry in the global descriptor list. If a descriptor is already installed with the specified FolderType and replaceFlag is false, an error is returned.

RemoveFolderDescriptor

pascal OSErr RemoveFolderDescriptor(FolderType foldType);

RemoveFolderDescriptor removes the specified entry from the global descriptor list.

GetFolderDescriptor

pascal OSErr GetFolderDescriptor(FolderType foldType,
                         Size descSize,
                         FolderDesc *foldDesc);

GetFolderDescriptor returns the folder descriptor information for the specified FolderType from the global descriptor list. descSize should be sizeof(FolderDesc).

GetFolderTypes

pascal OSErr GetFolderTypes(UInt32 requestedTypeCount,
                         UInt32 *totalTypeCount,
                         FolderType *theTypes);

GetFolderTypes returns the folder types from the global descriptor list. requestedTypeCount should be the number of FolderTypes that can fit in the buffer pointed to by theTypes. totalTypeCount returns the number of FolderTypes in the global list; if this is less than requestedTypeCount, then not all FolderTypes were returned to the caller. Pass nil for theTypes if only the total count of types is desired.

IdentifyFolder

pascal OSErr IdentifyFolder(short vReNum,
                         long dirID,
                         FolderType *foldType);

IdentifyFolder returns the folder type for the folder specified by vRefNum and dirID, if such a folder exists. Warning: IdentifyFolder may be slow, taking several seconds to complete. In addition, there may be multiple folder descriptors that map to an individual folder; IdentifyFolder will just return the FolderType of one of those descriptors.

Folder Routing Routines and Structures

The following routines can be used for providing routing information that will be used in future versions of the Finder for auto-routing items dropped into designated folders registered with the Extensible Folder Manager.

COMPATIBILITY NOTE:
Finder 8.0 does not support custom routing nor does it query the Extensible Folder Manager for routing information. Custom Routing will be supported in future versions of the Finder.

Folder Routing information software provides is as follows:

typedef UInt32 RoutingFlags;

The RoutingFlags describe special behavior applying to a routing. The defined bits are

enum {
      kPersistentRouting  = 1L << 0  /* routing persists across boots */
   };

Because persistent records create a system that can be "cleaned up" rebooting, software should use it only when there is no other way to initialize the descriptor after a reboot. Persistent routing is not currently supported in Mac OS 8.

typedef struct FolderRouting {
      Size          descSize;
      OSType        fileType;
      FolderType    routeFromFolder;
      FolderType    routeToFolder;
      RoutingFlags  flags;
   };

A FolderRouting is returned by GetFolderRoutings to describe a set of routing instructions.

AddFolderRouting

pascal OSErr AddFolderRouting(OSType fileType,
                         FolderType routeFromFolder, 
                         FolderType routeToFolder, 
                         RoutingFlags flags,
                         Boolean replaceFlag);

AddFolderRouting adds an entry to the folder routing table.

RemoveFolderRouting

pascal OSErr RemoveFolderRouting(OSType fileType,
                         FolderType routeFromFolder)

RemoveFolderRouting removes an entry from the routing table.

FindFolderRouting

pascal OSErr FindFolderRouting(OSType fileType,
                         FolderType routeFromFolder, 
                         FolderType *routeToFolder,
                         RoutingFlags *flags)

FindFolderRouting is used by clients to resolve a routing request specified by two criteria (fileType and routeFromFolder).

GetFolderRoutings

pascal OSErr GetFolderRoutings(UInt32 requestedRoutingCount, 
                         UInt32 *totalRoutingCount,
                         Size routingSize, 
                         FolderRouting *theRoutings);

GetFolderRoutings returns the folder descriptor information from the global routing list. requestedRoutingCount should be the number of FolderRoutings that can fit in the buffer pointed to by theRoutings. routingSize should be sizeof(FolderRouting). totalRoutingCount returns the number of FolderRoutings in the global list; if this is less than requestedRoutingCount, then not all FolderRoutings were returned to the caller. Pass nil for theRoutings if only the total count of routines is desired.

Further References


Acknowledgments

Thanks to Kevin Aitken, Jean-Pierre Ciudad, Steve Falkenburg, Pete Gontier, Winston Hendrickson, Erik Koebler
and Barb Kozlowski.

Send feedback to devsupport@apple.com
Updated: 12-September-97

Tech Support
Technotes | Previous Technote | Next Technote | Contents

Navigation graphic, see text links

Main | Page One | What's New | Apple Computer, Inc. | Find It | Contact Us | Help